﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

namespace MMDemo
{
    public enum StackOperateType
    {
        Hanoi, //汉若塔
        Queen, //皇后问题
        SeqStack,//顺序栈
        Pop,//出栈
        Push,//入栈
        SeqStackAuto,//自动入出栈的顺序栈
    }
    class AnimationStack:InterfaceDataStructs
    {
        //演示动画窗口的高度和宽度
        private int Animation_width = 0;
        private int Animation_height = 0;

        //双缓冲画布及Graphics
        public Bitmap BufferBmp = null;
        private Graphics BufferGrap = null;

        //动画的窗口对象
        private Form Animation_Form = null;
        private DrawHandler RefreshHandler = null;

        //盘子个数
        private int HanoiDiskNumber;
        //皇后个数
        private int QueenNum;
        
        //盘子坐标
        private int A_x = 0;
        private int B_x = 0;
        private int C_x = 0;
        private int ABC_y = 0;
        String path = Application.StartupPath;
        private Bitmap ChessBmp = null;
        private Bitmap WrongBmp = null;
        private Bitmap QueenBmp = null;
        private Bitmap RightBmp = null;
        private Bitmap DiskBmp = null;

        //棋子坐标
        private int Check_x = 0;
        private int Check_y = 0;

        private Button button1 = null;
        private Button button2 = null;
        private Bitmap TopBmp = null;

        private const int SPEED = 200;
        private int _Speed = SPEED;//演示动画速度
        public void SetSpeed(float scale)
        {
            _Speed = (int)(SPEED * scale);
        }

        List<PointF> QueenLocation = new List<PointF>();
        List<PointF> QueenFirstLocation = new List<PointF>();

        public AnimationStack(Form An_Form, DrawHandler refreshHandler, int An_Width, int An_Height)
        {
            this.Animation_Form = An_Form;
            this.RefreshHandler = refreshHandler;
            this.Animation_width = An_Width;
            this.Animation_height = An_Height;


            //设置画布和Graphics
            BufferBmp = new Bitmap(this.Animation_width, this.Animation_height);
            BufferGrap = Graphics.FromImage(BufferBmp);

            
            
            this.A_x = 120;
            this.B_x = this.Animation_width/2;
            this.C_x = this.Animation_width - 120;
            this.ABC_y = this.Animation_height - 250;
            QueenBmp = (Bitmap)Image.FromFile(path + "/StackSource/q.png");
            WrongBmp = (Bitmap)Image.FromFile(path + "/StackSource/w.png");
            RightBmp = (Bitmap)Image.FromFile(path + "/StackSource/r.png");
            DiskBmp = (Bitmap)Image.FromFile(path + "/StackSource/d.png");

            TopBmp = (Bitmap)Image.FromFile(path + "/StackSource/TopPointer.png");
        }



        private bool stop_flag = false;
        private bool PushExcute = false;
        private bool PopExcute = false;
        /// <summary>
        /// 动画演示
        /// </summary>
        public void Animation()
        {
            //DemoForm.AnimationThread.Suspend();
            if (GlobalStack.operateType == StackOperateType.SeqStack)
            {
                button1.Enabled = true;
                button2.Enabled = true;
            }
            while(true)
            {
                switch (GlobalStack.operateType)
                {
                    case StackOperateType.Hanoi:
                        stop_flag = Animation_Hanoi();
                        break;
                    case StackOperateType.Queen:
                        stop_flag = Animation_Queen();
                        break;
                    case StackOperateType.SeqStackAuto:
                        stop_flag = Animation_SeqStackAuto();
                        break;
                    default:
                        //button1.Enabled = true;
                        //button2.Enabled = true;
                        if (PushExcute)
                        {
                            DrawPush();
                            PushExcute = false;
                        }
                        if (PopExcute)
                        {
                            DrawPop();
                            PopExcute = false;
                        }
                        stop_flag = Animation_SeqStack();
                        break;
                }
                if (!stop_flag)
                {
                    MessageBox.Show(Animation_Form,"算法演示结束!");
                    break;
                }  
            }
            SysMainForm.AnimationForm.ChangeExcuteOverBtnsEnable();
        }
        public bool Animation_SeqStack()
        {
            if (PopArrayNum.Count == 7)
            {
                return false;
            } 
            else
            {
                return true;
            }
        }
        public int DoNum = 0;
        public bool Animation_SeqStackAuto()
        {
            for (int i = 0; i < PushPopElement.Length; ++i )
            {
                if (PushPopElement[i] == 1)
                {
                    SetExcuteLine(0);
                    SetExcuteLine(1);
                    SetExcuteLine(2);
                    SetExcuteLine(3); 
                    Thread.Sleep(SPEED);
                    DrawPush();
                    DoNum++;
                } 
                else
                {
                    SetExcuteLine(7);
                    SetExcuteLine(8);
                    SetExcuteLine(9);
                    SetExcuteLine(10);
                    Thread.Sleep(SPEED);
                    DrawPop();
                    DoNum++;
                }
            }
            return false;
        }
        public bool Animation_Queen()
        {
            Thread.Sleep(_Speed);
            SetQueenFirstLocation();
            DrawChessBoard();
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
            ShowQueen(QueenNum);
            return false;
        }
        
        public bool Animation_Hanoi()
        {
            Thread.Sleep(_Speed*5);
            hanoi_Move(HanoiDiskNumber, ref HanoiA, ref HanoiB, ref HanoiC);
            return false;
        }

        private void hanoi_Move(int n, ref List<int> A, ref List<int> B, ref List<int> C)
        {
            SetExcuteLine(1);
            SetExcuteLine(2);
            int temp;
            if (n == 0)
            {
                return;
            }
            SetExcuteLine(3);
            if (n == 1)
            {
                if (C.Count == HanoiDiskNumber)
                {
                    return;
                }
                else
                {
                    temp = A[A.Count - 1];
                    A.RemoveAt(A.Count - 1);
                    C.Add(temp);
                    SetExcuteLine(4);
                    DrawHanoi();
                    Thread.Sleep(_Speed*5);
                    return;
                }

            }
            else
            {
                SetExcuteLine(5);
                if (C.Count == HanoiDiskNumber)
                {
                    return;
                }
                else
                {
                    SetExcuteLine(6);
                    SetExcuteLine(7);
                    hanoi_Move(n - 1, ref A, ref C, ref B);
                    temp = A[A.Count - 1];
                    A.RemoveAt(A.Count - 1);
                    C.Add(temp);
                    SetExcuteLine(8);
                    DrawHanoi();
                    Thread.Sleep(_Speed*5);
                    SetExcuteLine(9);
                    hanoi_Move(n - 1, ref B, ref A, ref C);
                }
            }
        }

        List<int> HanoiA = new List<int>();
        List<int> HanoiB = new List<int>();
        List<int> HanoiC = new List<int>();
        public void SetA(int num)
        {
            for (int i = 0; i < num; i++)
            {
                HanoiA.Add(num - i);
            }
        }
        
        public void DrawHanoi()
        {
            BufferGrap.Clear(Color.Black);
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);

                Font font = new Font("微软雅黑", 20);
                SolidBrush brush = new SolidBrush(Color.Red);
                SolidBrush bursh_fill = new SolidBrush(Color.Green);
                PointF pf_A = new PointF(A_x - 15, ABC_y + 50);
                PointF pf_B = new PointF(B_x - 15, ABC_y + 50);
                PointF pf_C = new PointF(C_x - 15, ABC_y + 50);

                BufferGrap.DrawLine(new Pen(Color.Yellow, 5), new Point(A_x, ABC_y + 40), new Point(A_x, ABC_y - 200));
                BufferGrap.DrawLine(new Pen(Color.Yellow, 5), new Point(B_x, ABC_y + 40), new Point(B_x, ABC_y - 200));
                BufferGrap.DrawLine(new Pen(Color.Yellow, 5), new Point(C_x, ABC_y + 40), new Point(C_x, ABC_y - 200));
                BufferGrap.DrawString("A柱", font, brush, pf_A);
                BufferGrap.DrawString("B柱", font, brush, pf_B);
                BufferGrap.DrawString("C柱", font, brush, pf_C);
            
            for (int i = 0; i < HanoiA.Count; ++i)
            {
                BufferGrap.DrawImage(DiskBmp, A_x - HanoiA[i] * 20 + 1, ABC_y - 40 * i + 1 + 2 * i, HanoiA[i] * 40, 40);
            }
            for (int i = 0; i < HanoiB.Count; ++i)
            {
                BufferGrap.DrawImage(DiskBmp, B_x - HanoiB[i] * 20, ABC_y - 40 * i + 2 * i, HanoiB[i] * 40, 40);
            }
            for (int i = 0; i < HanoiC.Count; ++i)
            {
                BufferGrap.DrawImage(DiskBmp, C_x - HanoiC[i] * 20, ABC_y - 40 * i + 2 * i, HanoiC[i] * 40, 40);
            }
            Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        private void SetQueenFirstLocation()
        {
            Check_x = this.Animation_width / 2 + QueenNum * 25;
            Check_y = this.Animation_height/ 2 - QueenNum * 25 - 70;

            for(int i = 0; i < QueenNum; ++i)
            {
                PointF pf = new PointF(Check_x - i * 50 - 50,Check_y);
                QueenFirstLocation.Add(pf);
            }
        }
        public void DrawChessBoard()
        {
            BufferGrap.DrawImage(ChessBmp,this.Animation_width/2 - ChessBmp.Width/2,this.Animation_height/2 - ChessBmp.Height/2);
            //Refresh();
        }
        public void DrawQueen(ref List<PointF> A, ref List<PointF> B)
        {
            DrawChessBoard();
            for (int i = 0; i < A.Count; ++i)
            {
                BufferGrap.DrawImage(QueenBmp, QueenFirstLocation[i].X, QueenFirstLocation[i].Y);
            }
            for (int j = 0; j < B.Count; ++j)
            {
                BufferGrap.DrawImage(QueenBmp, QueenLocation[j].X, QueenLocation[j].Y);
            }
            //Thread.Sleep(200);
            Refresh();
        }

        //储存数组，DQueen[line] = row表示第row行第line列放一个皇后
        
        private void ShowQueen(int QueenNum)
        {
            Check_x = this.Animation_width / 2 - QueenNum * 25;
            Check_y = this.Animation_height / 2 - QueenNum * 25;

            int[] DQueen = new int[QueenNum+1];

            SetExcuteLine(6);

            //line --> 列；row --> 行
            for (int line = 1; line <= QueenNum; ++line)
            {
                //PointF temp = QueenFirstLocation[QueenFirstLocation.Count - 1];
                //QueenFirstLocation.RemoveAt(QueenFirstLocation.Count - 1);

                SetExcuteLine(7);
                SetExcuteLine(8);
                int row;
                for (row = DQueen[line] + 1; row <= QueenNum; ++row)
                {
                    //当前位置是否可用，默认可用
                    bool isOk = true;
                    QueenLocation.Add(new PointF(Check_x + (line - 1) * 50, Check_y + (row - 1) * 50));
                    DrawQueen(ref QueenFirstLocation, ref QueenLocation);
                    Thread.Sleep(_Speed);
                    //检查当前列当前行可否放皇后
                    for (int i = 1; i < line; ++i)
                    {
                        SetExcuteLine(9);
                        if (DQueen[i] == row || Math.Abs(DQueen[i] - row) == Math.Abs(i - line))//当前位置不可用
                        {
                            for (int m = 1; m < line; ++m)
                            {
                                if (Math.Abs(DQueen[m] - row) == Math.Abs(m - line))
                                {
                                    BufferGrap.DrawImage(WrongBmp, new PointF(Check_x + (m - 1) * 50, Check_y + (DQueen[m] - 1) * 50));
                                } 
                                if (DQueen[m] == row)
                                {
                                    BufferGrap.DrawImage(WrongBmp, new PointF(Check_x + (m - 1) * 50, Check_y + (row - 1) * 50));
                                }
                            }
                            BufferGrap.DrawImage(WrongBmp, new PointF(Check_x + (line - 1) * 50, Check_y + (row - 1) * 50));
                            Refresh();
                            Thread.Sleep(_Speed);
                            QueenLocation.RemoveAt(QueenLocation.Count - 1);
                            DrawQueen(ref QueenFirstLocation, ref QueenLocation);
                            isOk = false;                            
                            break;
                        }
                    }
                    SetExcuteLine(10);
                    if (isOk)
                    {   //当前位置可用
                        SetExcuteLine(11);
                        BufferGrap.DrawImage(RightBmp, new PointF(Check_x + (line - 1) * 50, Check_y + (row - 1) * 50));
                        Refresh();
                        Thread.Sleep(_Speed);
                        DQueen[line] = row;
                        if (line == QueenNum)
                        {
                            SetExcuteLine(14);
                            SetExcuteLine(15);
                            MessageBox.Show(Animation_Form,"得要一种方案！");
                            SetExcuteLine(16);
                            SetExcuteLine(17);
                            QueenLocation.RemoveAt(QueenLocation.Count - 1);
                            DrawQueen(ref QueenFirstLocation, ref QueenLocation);
                            Thread.Sleep(_Speed);
                        }
                        else
                        {
                            SetExcuteLine(12);
                            SetExcuteLine(13);
                            //否则跳出当前列，进入下一列
                            break;
                        }
                    }

                }
                if (row == QueenNum + 1)
                {
                    //当前列已经搜索完，回退到上一列
                    
                    DQueen[line] = 0; //将当前列清零，保证下一次搜索该列时从第1行开始
                    if (QueenLocation.Count - 1 > -1)
                    {
                        QueenLocation.RemoveAt(QueenLocation.Count - 1);
                        DrawQueen(ref QueenFirstLocation,ref QueenLocation);
                        Thread.Sleep(_Speed);
                        line -= 2; //for语句还要进行+1操作，减2才是回退1列
                    }
                    else
                    {
                        break;
                    }
                }
                if (line == -1)//第一列已经搜索完毕，算法结束
                {
                    //MessageBox.Show(Animation_Form,"演示结束！");
                    break;
                }
            }
        }

        public void SetButton()
        {
            button1 = new Button();
            button1.Name = "button1";
            button1.Text = "入栈";
            button1.Size = new Size(70, 30);
            button1.Location = new Point(this.Animation_width / 2 - 200, this.Animation_height / 2 + 200);
            button1.Visible = true;
            button1.Enabled = false;
            this.Animation_Form.Controls.Add(button1);
            button1.BringToFront();
            button1.Click += new EventHandler(button1_Click);

            button2 = new Button();
            button2.Name = "button2";
            button2.Text = "出栈";
            button2.Size = new Size(70, 30);
            button2.Location = new Point(this.Animation_width / 2 + 200, this.Animation_height / 2 + 200);
            button2.Visible = true;
            button2.Enabled = false;
            this.Animation_Form.Controls.Add(button2);
            button2.BringToFront();
            button2.Click += new EventHandler(button2_Click);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = false;
            SetExcuteLine(0);
            SetExcuteLine(1);
            SetExcuteLine(2);
            SetExcuteLine(3);
            if (StackArrayNum.Count == 4)
            {
                SetExcuteLine(4);
                MessageBox.Show(Animation_Form, "栈满，不能继续进行入栈操作！");
                button1.Enabled = true;
                button2.Enabled = true;
                SetExcuteLine(7);
            }
            else if (PushArrayNum.Count == 0)
            {
                MessageBox.Show(Animation_Form, "进栈序列空，无法入栈！");
                button1.Enabled = true;
                button2.Enabled = true;
            }
            else
            {
                //DrawPush();
                PushExcute = true;
            }
        }
        //private void Run()
        //{
        //    switch(GlobalStack.operateType)
        //    {
        //        case StackOperateType.Push:
        //            DrawPush();
        //            break;
        //        case StackOperateType.Pop:
        //            button2.Enabled = false;
        //            button1.Enabled = false;
        //            DrawPop();
        //            button2.Enabled = true;
        //            button1.Enabled = true; 
        //            break;
        //    }
        //}
        private void DrawPush()
        {
            SetExcuteLine(4);
            DrawAll();
            DrawPointer(StackArrayNum.Count + 1);  
            DrawPushPopElement(DoNum);
            Refresh();
            Thread.Sleep(SPEED);
            SetExcuteLine(5);
            String temp = PushArrayNum[PushArrayNum.Count - 1];
            PushArrayNum.RemoveAt(PushArrayNum.Count - 1);
            int MoveStep = 5;
            int x = PushArrayNum.Count * 30 + 30;
            int y = 130;
            while (x < Animation_width / 2 - 3 - 12)
            {
                x += MoveStep;
                Thread.Sleep(SPEED / 2);
                DrawAll();
                DrawPointer(StackArrayNum.Count + 1);
                DrawPushPopElement(DoNum);
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15),
                    new SolidBrush(Color.Yellow), new Point(x, y));
                Refresh();

            }
            while (y < 370 - StackArrayNum.Count * 50 - 5)
            {
                y += MoveStep;
                Thread.Sleep(SPEED / 2);
                DrawAll();
                DrawPointer(StackArrayNum.Count +　1);
                DrawPushPopElement(DoNum);
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15),
                    new SolidBrush(Color.Yellow), new PointF(x, y));
                Refresh();
            }
            StackArrayNum.Add(temp);
            DrawAll();
            DrawPointer(StackArrayNum.Count);
            DrawPushPopElement(DoNum);
            Refresh();
            SetExcuteLine(6);
            if (GlobalStack.operateType == StackOperateType.SeqStack)
            {
                button1.Enabled = true;
                button2.Enabled = true;
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = false;
            SetExcuteLine(7);
            SetExcuteLine(8);
            SetExcuteLine(9);
            SetExcuteLine(10);
            //GlobalStack.operateType = StackOperateType.Pop;
            //Thread th = new Thread(new ThreadStart(Run));
            if (StackArrayNum.Count == 0)
            {
                SetExcuteLine(11);
                MessageBox.Show(Animation_Form, "栈空，不能继续进行出栈操作！");
                button1.Enabled = true;
                button2.Enabled = true;
                SetExcuteLine(14);
            }
            else
            {
                //DrawPop();
                PopExcute = true;
            }
            
        }
        private void DrawPop()
        {
            SetExcuteLine(12);
            String temp = StackArrayNum[StackArrayNum.Count - 1];
            StackArrayNum.RemoveAt(StackArrayNum.Count - 1);
            int MoveStep = 5;
            int x = this.Animation_width / 2 - 3 - 7;
            int y = 370 - StackArrayNum.Count * 50;
            while (y > 130)
            {
                y -= MoveStep;
                Thread.Sleep(SPEED / 2);
                DrawAll();
                DrawPointer(StackArrayNum.Count);
                DrawPushPopElement(DoNum);
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15),
                    new SolidBrush(Color.Yellow), new PointF(x, y));
                Refresh();
            }
            while (x < this.Animation_width - 60  - PopArrayNum.Count * 50)
            {
                x += MoveStep;
                Thread.Sleep(SPEED / 2);
                DrawAll();
                DrawPointer(StackArrayNum.Count);
                DrawPushPopElement(DoNum);
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15),
                    new SolidBrush(Color.Yellow), new PointF(x, y));
                Refresh();
            }

            PopArrayNum.Add(temp);
            Thread.Sleep(SPEED / 2);
            DrawAll();
            DrawPointer(StackArrayNum.Count);
            DrawPushPopElement(DoNum);
            Refresh();
            SetExcuteLine(13);
            SetExcuteLine(14);
            if (GlobalStack.operateType == StackOperateType.SeqStack)
            {
                button1.Enabled = true;
                button2.Enabled = true;
            }
        }
        private void DrawPushPopElement(int n)
        {
            if (GlobalStack.operateType == StackOperateType.SeqStackAuto)
            {
                BufferGrap.DrawString("操作序列:", new Font("微软雅黑", 15), new SolidBrush(Color.Red),
                                new PointF(this.Animation_width / 2 - 280, this.Animation_height / 2 + 200));
                for (int i = 0; i < PushPopElement.Length; ++i)
                {
                    BufferGrap.DrawString(PushPopElement[i].ToString(), new Font("微软雅黑", 15), new SolidBrush(Color.Red),
                        new PointF(this.Animation_width / 2 - 180 + i * 30, this.Animation_height / 2 + 200));
                }
                if (n != -1)
                {
                    BufferGrap.DrawString(PushPopElement[n].ToString(), new Font("微软雅黑", 15), new SolidBrush(Color.Yellow),
                        new PointF(this.Animation_width / 2 - 180 + n * 30, this.Animation_height / 2 + 200));
                }
                BufferGrap.DrawString("0表示出栈，1表示入栈", new Font("微软雅黑", 15), new SolidBrush(Color.Yellow), new PointF(this.Animation_width / 2 - 100, this.Animation_height / 2 + 250));
            }
        }
        List<String> PopArrayNum = new List<String>();
        List<String> PushArrayNum = new List<String>();
        List<String> StackArrayNum = new List<String>();
        private void SetPushArrayNum()
        {
            PushArrayNum.Add("G");
            PushArrayNum.Add("F");
            PushArrayNum.Add("E");
            PushArrayNum.Add("D");
            PushArrayNum.Add("C");
            PushArrayNum.Add("B");
            PushArrayNum.Add("A");
        }
        int[] PushPopElement = new int [14];
        private void GetPushPopElement()
        {
            int StackFlag = 0;
            int StackNum = 0;
            Random ran = new Random();
            for (int i = 0; i < 14; i++)
            {
                int r = ran.Next(0, StackFlag + 1);
                if (r == 0 && StackFlag < 4 && StackNum < 7)
                {
                    StackNum++;
                    StackFlag += 1;
                    PushPopElement[i] = 1;
                }
                else
                {
                    StackFlag -= 1;
                    PushPopElement[i] = 0;
                }
            }
        }
        private void DrawAll()
        {
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
            DrawPopArray();
            DrawStackBuffer();
            DrawStackElement();
            DrawPushArray();
        }
        private void DrawPushArray()
        {
            BufferGrap.DrawLine(new Pen(Color.Blue, 4), new Point(30, 160), new Point(240, 160));
            BufferGrap.DrawString("进栈序列", new Font("微软雅黑", 15), new SolidBrush(Color.Blue), new Point(60, 165));
            for (int i = 0; i < PushArrayNum.Count; ++i)
            {
                BufferGrap.DrawString(PushArrayNum[i], new Font("微软雅黑", 15), new SolidBrush(Color.Yellow), new PointF(30 + i * 30, 130));
            }
        }
        private void DrawPopArray()
        {
            BufferGrap.DrawLine(new Pen(Color.Blue, 4), new Point(this.Animation_width - 240, 160), new Point(this.Animation_width - 30, 160));
            BufferGrap.DrawString("出栈序列", new Font("微软雅黑", 15), new SolidBrush(Color.Blue), new Point(this.Animation_width - 210, 165));
            for (int i = 0; i < PopArrayNum.Count; ++i)
            {
                BufferGrap.DrawString(PopArrayNum[i], new Font("微软雅黑", 15), new SolidBrush(Color.Yellow), new PointF(this.Animation_width - 60 - i * 30, 130));
            }
        }
        private void DrawStackElement()
        {
            for (int i = 0; i < StackArrayNum.Count; ++i)
            {
                BufferGrap.DrawString(StackArrayNum[i], new Font("微软雅黑", 15),
                    new SolidBrush(Color.GreenYellow), new PointF(Animation_width / 2 - 3- 7, 370 - i * 50));
            }
        }
        private void DrawPointer(int n)
        {
            BufferGrap.DrawImage(TopBmp, new Point(Animation_width / 2 - 120, 400 - (n - 1) * 50 - 40));
        }
        private void DrawStackBuffer()
        {
            BufferGrap.DrawLine(new Pen(Color.Red, 4),
                new Point(Animation_width / 2 - 50, 200), new Point(Animation_width / 2 - 50, 400));
            BufferGrap.DrawLine(new Pen(Color.Red, 4),
                new Point(Animation_width / 2 + 50, 200), new Point(Animation_width / 2 + 50, 400));
            for (int i = 0; i < 1; ++i)
            {
                BufferGrap.DrawLine(new Pen(Color.Red, 4),
                new Point(Animation_width / 2 - 50, 400 - i * 50), new Point(Animation_width / 2 + 50, 400 - i * 50));
            }
        }
        /// <summary>
        /// 初始化数据
        /// </summary>
        public void InitData()
        {
            ResetBuffer(Animation_width, Animation_height);
            switch (GlobalStack.operateType)
            {
                case StackOperateType.Hanoi:
                    ResetData(GlobalStack.HanoiDiskNum); 
                    break;
                case StackOperateType.Queen:
                    ResetData(GlobalStack.QueenNum); 
                    break;
                case StackOperateType.SeqStackAuto:
                    ResetData(0);
                    break;
                default:
                    ResetData(0);
                    break;
            }
            Refresh();
        }
        /// <summary>
        /// 恢复数据
        /// </summary>
        public void ResetData()
        {
            InitData();
        }
        public void ResetData(int num)
        {
            switch (GlobalStack.operateType)
            {
                case StackOperateType.Hanoi:
                    this.HanoiDiskNumber = num;
                    BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
                    HanoiA.Clear();
                    HanoiB.Clear();
                    HanoiC.Clear();
                    SetA(num);
                    DrawHanoi();
            	    break;
                case StackOperateType.Queen:
                    this.QueenNum = num;
                    BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
                    ChessBmp = (Bitmap)Image.FromFile(path + "/StackSource/" + GlobalStack.QueenNum + ".png");
                    DrawChessBoard();
                    QueenFirstLocation.Clear();
                    SetQueenFirstLocation();
                    QueenLocation.Clear();
                    DrawQueen(ref QueenFirstLocation, ref QueenLocation);
                    break;
                case StackOperateType.SeqStackAuto:
                    BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
                    GetPushPopElement();
                    PushArrayNum.Clear();
                    PopArrayNum.Clear();
                    StackArrayNum.Clear();
                    SetPushArrayNum();
                    DrawAll();
                    DrawPointer(StackArrayNum.Count);
                    DrawPushPopElement(-1);
                    break;
                default:
                    BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
                    SetButton();
                    PushArrayNum.Clear();
                    PopArrayNum.Clear();
                    StackArrayNum.Clear();
                    SetPushArrayNum();
                    DrawAll();
                    DrawPointer(StackArrayNum.Count);
                    PushExcute = false;
                    PopExcute = false;
                    break;
            }
        }
       
        /// <summary>
        /// 重新设置画布
        /// </summary>
        public void ResetBuffer(int Width, int Height)
        {
            this.Animation_width = Width;
            this.Animation_height = Height;
            if (null != BufferBmp)
            {
                BufferBmp.Dispose();
                BufferBmp = null;
            }
            if (null != BufferGrap)
            {
                BufferGrap.Dispose();
                BufferGrap = null;
            }

            BufferBmp = new Bitmap(this.Animation_width, this.Animation_height);
            BufferGrap = Graphics.FromImage(BufferBmp);
            
        }
        /// <summary>
        /// 得到双缓冲画布
        /// </summary>
        public Bitmap GetBufferBmp()
        {
            return BufferBmp;
        }
        private bool Refresh()
        {
            try
            {
                if (Animation_Form.IsHandleCreated)
                    Animation_Form.Invoke(RefreshHandler);
            }
            catch (Exception ex)
            {
                MessageBox.Show(Animation_Form,ex.Message);
                return false;
            }
            return true;
        }
        private void SetExcuteLine(int line)
        {
            if (line != GlobalLink.cur_line)
            {
                GlobalLink.cur_line = line;
                Thread.Sleep((int)(1000 * PublicDataClass.scale));
                SysMainForm.AnimationForm.SetSelectLine(line);
            }
        }
    }
}
